package org.apogee.mil.client.main.pages.admin.forms;

import java.util.ArrayList;
import java.util.List;

import org.apogee.mil.client.factories.ServerServiceFactory;
import org.apogee.mil.client.utils.Session;
import org.apogee.mil.shared.Question;
import org.apogee.mil.shared.User;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.VerticalAlignment;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.Label;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.Radio;
import com.extjs.gxt.ui.client.widget.form.RadioGroup;
import com.extjs.gxt.ui.client.widget.form.TextArea;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.FormPanel.LabelAlign;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class AdminQuestionForm extends LayoutContainer {
	private User currentUser;
	private List<Question> questions;
	private List<Question> correct;
	private List<Question> wrong;
	private FormData data;
	private FormPanel panel;

	private TextArea question;
	private TextArea choice1;
	private TextArea choice2;
	private TextArea choice3;
	private TextArea choice4;

	private TextField<String> answerField;
	private TextField<String> volumeField;
	private Radio enableBox;
	private Radio disableBox;
	private Radio reviewBox;
	private Radio testBox;
	private Button submit;

	private int currentQuestion = 0;


	public AdminQuestionForm(List<Question> questions) {
		this.currentUser = ServerServiceFactory.getUser(Session.getSessionId());;
		this.questions = questions;

		this.correct = new ArrayList<Question>();
		this.wrong = new ArrayList<Question>();
	}


	protected void onRender(Element parent, int pos) {
		super.onRender(parent, pos);

		data = new FormData("100%");
		

		panel = new FormPanel();
		panel.setFrame(true);
		panel.setBorders(true);
		panel.setSize(600, 600);
		panel.setBodyBorder(true);
		panel.setLabelAlign(LabelAlign.RIGHT);
		panel.setLabelWidth(100);
		panel.setButtonAlign(HorizontalAlignment.LEFT);


		question = new TextArea();
		question.setSize(700, 100);
		question.setFieldLabel("Question");

		panel.add(question, data);

		choice1 = new TextArea();
		choice1.setSize(700, 50);
		choice1.setFieldLabel("1-A");

		panel.add(choice1, data);

		choice2 = new TextArea();
		choice2.setSize(700, 50);
		choice2.setFieldLabel("2-B");

		panel.add(choice2, data);

		choice3 = new TextArea();
		choice3.setSize(700, 50);
		choice3.setFieldLabel("3-C");

		panel.add(choice3, data);

		choice4 = new TextArea();
		choice4.setSize(700, 50);
		choice4.setFieldLabel("4-D");

		panel.add(choice4, data);


		answerField = new TextField<String>();
		answerField.setWidth(100);
		answerField.setFieldLabel("Answer");
		panel.add(answerField);

		volumeField = new TextField<String>();
		volumeField.setWidth(100);
		volumeField.setFieldLabel("Volume");
		panel.add(volumeField);

		reviewBox = new Radio();
		reviewBox.setBoxLabel("Review Question");
		
		testBox = new Radio();
		testBox.setBoxLabel("Test Question");
		
		RadioGroup cbg = new RadioGroup();
		cbg.setFieldLabel("Question Type");
		cbg.add(reviewBox);
		cbg.add(testBox);
		
		panel.add(cbg, data);
		
		enableBox = new Radio();
		enableBox.setBoxLabel("Enabled");
		
		disableBox = new Radio();
		disableBox.setBoxLabel("Disabled");
		
		cbg = new RadioGroup();
		cbg.setFieldLabel("Enable Question");
		cbg.add(enableBox);
		cbg.add(disableBox);
		
		panel.add(cbg, data);		
		
		submit = new Button("Submit");
		submit.setEnabled(false);
		submit.setToolTip("Submit Correction/New Question");
		submit.setWidth(100);
		submit.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				submitQuestion();
				getCurrentQuestion();

			}
		});


		Button add = new Button("Add");
		add.setToolTip("Add Question");
		add.setWidth(100);
		add.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				addQuestion();
				getCurrentQuestion();
			}
		});

		String nbsp = "";

		for (int i = 0; i < 65; i++)
			nbsp += "&nbsp;";


		panel.add(new Label(nbsp));
		panel.add(new Label(nbsp));
		panel.add(new Label(nbsp));

		HorizontalPanel hp = new HorizontalPanel();
		hp.setHorizontalAlign(HorizontalAlignment.CENTER);


		VerticalPanel vp = new VerticalPanel();
		vp.setVerticalAlign(VerticalAlignment.MIDDLE);
		vp.setHorizontalAlign(HorizontalAlignment.CENTER);

		hp.add(new Label(nbsp));

		hp.add(submit);
		vp.add(hp);

		hp = new HorizontalPanel();
		hp.setHorizontalAlign(HorizontalAlignment.CENTER);

		Button next = new Button(">>");
		next.setToolTip("Next Quesiton");
		next.setWidth(50);
		next.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				wrong.add(questions.get(currentQuestion));
				currentQuestion++;
				if (currentQuestion == questions.size()) 
					currentQuestion = 0;

				getCurrentQuestion();

			}

		});

		Button prev = new Button("<<");
		prev.setToolTip("Previous Question");
		prev.setWidth(50);
		prev.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				currentQuestion--;
				if (wrong.contains(questions.get(currentQuestion))) {
					wrong.remove(questions.get(currentQuestion));
				} else if (correct.contains(questions.get(currentQuestion))) {
					correct.remove(questions.get(currentQuestion));
				}
				currentQuestion = currentQuestion < 0 ? 0 : currentQuestion;

				getCurrentQuestion();
			}
		});

		hp.add(new Label(nbsp));
		hp.add(prev);
		hp.add(next);

		vp.add(hp);

		hp = new HorizontalPanel();
		hp.setHorizontalAlign(HorizontalAlignment.CENTER);
		hp.add(new Label(nbsp));
		hp.add(add);

		vp.add(hp);

		panel.add(vp, data);

		add(panel);
		layout();

		Begin();
	}



	private void Begin() {

		getCurrentQuestion();

	}


	private void getCurrentQuestion() {
		if (questions.size() == 0) {
			return;
		}
		submit.setEnabled(true);

		if (currentQuestion == questions.size()) 
			currentQuestion = 0;


		Question current = questions.get(currentQuestion);

		panel.setHeading("Question " + (currentQuestion+1) + " out of " + questions.size());

		if (current.getQuestion().trim().equals("")) {
			return;
		}

		question.setValue(current.getQuestion());

		choice1.setValue(current.getChoice(0));
		choice2.setValue(current.getChoice(1));
		choice3.setValue(current.getChoice(2));
		choice4.setValue(current.getChoice(3));

		answerField.setValue(String.valueOf(current.getAnswer()));

		if (current.getEnabled() == true) {
			enableBox.setValue(true);
			disableBox.setValue(false);
		} else {
			enableBox.setValue(false);
			disableBox.setValue(true);
		}
		
		volumeField.setValue(String.valueOf(current.getVolume()));

		String type = current.getType();
		
		if (type.toLowerCase().trim().equals("r")) {
			reviewBox.setValue(true);
			testBox.setValue(false);
		} else {
			reviewBox.setValue(false);
			testBox.setValue(true);
		}


		panel.layout();
		panel.repaint();

	}

	private void addQuestion() {
		Question q = new Question();
		q.setId(-1);
		question.setValue("");

		choice1.setValue("");
		choice2.setValue("");
		choice3.setValue("");
		choice4.setValue("");

		answerField.setValue("");

		enableBox.setValue(true);
		volumeField.setValue("");

		questions.add(q);

		currentQuestion = questions.size() - 1;

		panel.layout();
		panel.repaint();

	}

	private void submitQuestion() {
		if (questions.size() == 0) {
			return;
		}
		
		panel.mask("Please Wait...");
		Question current = questions.get(currentQuestion);

		current.setQuestion(question.getValue());

		ArrayList<String> choices = new ArrayList<String>();
		choices.add(choice1.getValue());
		choices.add(choice2.getValue());
		choices.add(choice3.getValue());
		choices.add(choice4.getValue());

		current.setChoices(choices);
		try {
			current.setAnswer(Integer.parseInt(answerField.getValue().trim())); 
		} catch (Exception ex) {
			MessageBox.alert("Error", "Answer field needs to be of numerical value", null);
			return;
		}
		
		try {
			current.setVolume(Integer.parseInt(volumeField.getValue().trim())); 
		} catch (Exception ex) {
			MessageBox.alert("Error", "Volume field needs to be of numerical value", null);
			return;
		}
		
		if (enableBox.getValue() == true) {
			current.setEnabled(true);
		} else {
			current.setEnabled(false);
		}
		
		String type = "T";
		if (reviewBox.getValue() == true) {
			type = "R";
		}
		
		current.setType(type);
		
		ServerServiceFactory.getAdminService(currentUser.getSessionId()).updateQuestion(currentUser.getCurrentTest(), current, new AsyncCallback<Boolean>() {

			@Override
			public void onFailure(Throwable caught) {
				panel.unmask();
				MessageBox.alert("Error", "An Exception was Thrown. Please Check Logs", null);
			}

			@Override
			public void onSuccess(Boolean result) {
				panel.unmask();
				if (result.booleanValue() == false) {
					MessageBox.alert("Error", "Unable to update question", null);
				} else {
					Info.display("Success", "Question Successfully Updated/Added");
				}
				
			}
		});
	}

}
